﻿using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Forms;
using System.ComponentModel;
using System.Data;
using System.Windows.Controls;

namespace GPVC
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            //
            dataTable = CreateEmptyDataGrid();
            FileListDataGrid.ItemsSource = dataTable.DefaultView;
        }

        private readonly DataTable dataTable;
        private static List<RasterIO.GeoTiffInfo> geoTiffInfoList;
        private List<string> tmpFileInfo;
        private static List<List<string>> fileListInfo;
        private static ExcelIO.ExcelInfo excelInfo;

        private DataTable CreateEmptyDataGrid()
        {
            DataTable emptyDataTable = new DataTable();
            emptyDataTable.Columns.Add("影像文件", typeof(string));
            emptyDataTable.Columns.Add("像元值文件", typeof(string));
            //
            for (var i = 0; i < 10; i++)
            {
                DataRow emptyRow = emptyDataTable.NewRow();
                emptyDataTable.Rows.Add(emptyRow);
            };
            return emptyDataTable;
        }

        private void UpdateDataTable(List<List<string>> fileNameData)
        {
            var i = 0;
            foreach (List<string> fileName in fileNameData)
            {
                if (dataTable.Rows.Count <= i)
                {
                    DataRow emptyRow = dataTable.NewRow();
                    dataTable.Rows.Add(emptyRow);
                }
                dataTable.Rows[i][0] = System.IO.Path.GetFileName(fileName[0]);
                dataTable.Rows[i][1] = fileName[1];
                i++;
            }
        }

        private void ClearDataTable()
        {
            for (var i = 0; i < dataTable.Rows.Count; i++)
            {
                dataTable.Rows[i][0] = "";
                dataTable.Rows[i][1] = "";
            }
        }

        private void SetImgFileInfo2TextBox(RasterIO.GeoTiffInfo geoTiffInfo)
        {
            var fileName = "文件名：" + geoTiffInfo.fileName + "\r\n";
            var bandCount = "波段数：" + geoTiffInfo.bandCount.ToString() + "\r\n";
            var imgSize = "图像尺寸：" + '(' + geoTiffInfo.height.ToString() + ',' +
                                                geoTiffInfo.width.ToString() + ')' + "\r\n";
            var spatialResolution = "空间分辨率：" + '(' + geoTiffInfo.spatialResolution[0].ToString() + ',' +
                                                                  geoTiffInfo.spatialResolution[1].ToString() + ')' + "\r\n";
            var geoTransform = "仿射变换系数：" + '(' + geoTiffInfo.transform[0].ToString() + ',' +
                                                    geoTiffInfo.transform[1].ToString() + ',' +
                                                    geoTiffInfo.transform[2].ToString() + ',' +
                                                    geoTiffInfo.transform[3].ToString() + ',' +
                                                    geoTiffInfo.transform[4].ToString() + ',' +
                                                    geoTiffInfo.transform[5].ToString() + ')' + "\r\n";
            //
            geoTiffInfo.gcs.ExportToWkt(out string gcsInfo);
            geoTiffInfo.pcs.ExportToWkt(out string pcsInfo);
            //
            var gcs = "地理坐标系信息：" + gcsInfo + "\r\n";
            var pcs = "投影坐标系信息：" + pcsInfo + "\r\n";
            //
            var enterLine = "------------------------------------------------------\r\n";
            //
            var textInfo = fileName + bandCount + imgSize + spatialResolution + geoTransform + gcs + pcs + enterLine;
            DisplayFileInfoTextBox.AppendText(textInfo);
        }

        private void SetExcelInfo2TextBox(ExcelIO.ExcelInfo excelInfo)
        {
            var excelFileName = "文件名：" + excelInfo.fileName + "\r\n";
            var countWorkSheet = "工作表数：" + excelInfo.countWorkSheet.ToString() + "\r\n";
            DisplayFileInfoTextBox.AppendText(excelFileName + countWorkSheet);
            //
            var workSheetInfo = excelInfo.workSheetInfo;
            foreach (var tmpWorkSheetInfo in workSheetInfo)
            {
                var tmpInfo = tmpWorkSheetInfo.Item1 + "：（" + tmpWorkSheetInfo.Item2[0].ToString() + "," +
                               tmpWorkSheetInfo.Item2[1].ToString() + "）" + "\r\n";
                DisplayFileInfoTextBox.AppendText(tmpInfo);
                //
                ChooseWorkingSheetComboBox.Items.Add(tmpWorkSheetInfo.Item1);
            }
            DisplayFileInfoTextBox.AppendText("------------------------------------------------------\r\n");
        }

        private List<List<double>> DeepCopyList(List<List<double>> srcList)
        {
            List<List<double>> dstList = new List<List<double>>();
            foreach (List<double> subList in srcList)
            {
                List<double> tmpList = new List<double>();
                foreach (double value in subList)
                {
                    tmpList.Add(value);
                }
                dstList.Add(tmpList);
            }
            return dstList;
        }

        private int SumBandCount()
        {
            var bandCount = 0;
            for (var i = 0; i < geoTiffInfoList.Count; i++)
            {
                bandCount += geoTiffInfoList[i].bandCount;
            }
            return bandCount;
        }

        private void ApplyGPVC()
        {
            ExcelIO excelIO = new ExcelIO();
            var excelData = excelIO.ReadExcel(excelInfo.fileName,
                                              ChooseWorkingSheetComboBox.SelectedItem.ToString(),
                                              ChooseXFieldNameComboBox.SelectedItem.ToString(),
                                              ChooseYFieldNameComboBox.SelectedItem.ToString());
            //var coordinatesTypeString = ChooseCoordinatesTypeComboBox.Text;
            var coordinatesTypeString = (ChooseCoordinatesTypeComboBox.SelectedItem as ComboBoxItem).Content.ToString();
            string coordinatesType;
            if (coordinatesTypeString == "地理坐标") coordinatesType = "LONLAT";
            else if (coordinatesTypeString == "投影坐标") coordinatesType = "XY";
            else coordinatesType = "ROWCOL";

            //
            var tmpSaveData = DeepCopyList(excelData);
            //
            var totalBandCount = SumBandCount();
            var iterCount = totalBandCount * excelData.Count;
            var fileCount = fileListInfo.Count;
            var i = 0;
            int currentCount;
            int statusPercent;
            int unprocessingCount = 0;
            foreach (List<string> fileName in fileListInfo)
            {
                var saveData = DeepCopyList(tmpSaveData);
                var saveFilePath = ChooseSaveDirTextBox.Text + "\\" + fileName[1];
                //
                for (var j = 1; j <= geoTiffInfoList[i].bandCount; j++)
                {
                    var bandArr = RasterIO.ReadGeoTiff(geoTiffInfoList[i], j);
                    //
                    for (var k = 0; k < saveData.Count; k++)
                    {
                        double[] coordinates = { saveData[k][1], saveData[k][2] };
                        var pixelValue = GetPixelValuesByCoordinates.GetPixelValues(bandArr,
                                                                                    geoTiffInfoList[i].width,
                                                                                    geoTiffInfoList[i].hasPCS,
                                                                                    geoTiffInfoList[i].gcs,
                                                                                    geoTiffInfoList[i].pcs,
                                                                                    geoTiffInfoList[i].transform,
                                                                                    coordinates,
                                                                                    coordinatesType);
                        //if (double.IsNaN(pixelValue))
                        //{
                        //    var dlgResult = System.Windows.MessageBox.Show("坐标文件中的坐标可能存在错误，比如坐标超出图像的范围。请检查您输入的Excel坐标文件！",
                        //                                    "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                        //}
                        saveData[k].Add(pixelValue);
                        //
                        if (i == 0)
                        {
                            currentCount = (((k + 1) + (saveData.Count * (j - 1)) + i * geoTiffInfoList[i].bandCount * saveData.Count));
                            statusPercent = Convert.ToInt32(Math.Round(Convert.ToDouble(currentCount / (double)iterCount) * 100));
                        }
                        else
                        {
                            currentCount = (((k + 1) + (saveData.Count * (j - 1)) + i * geoTiffInfoList[i - 1].bandCount * saveData.Count));
                            statusPercent = Convert.ToInt32(Math.Round(Convert.ToDouble(currentCount / (double)iterCount) * 100));
                        }
                        if (statusPercent > 95) statusPercent = 95;
                        //
                        excelData[k].Add(pixelValue);
                        ExtractionStatusProgressBar.Value = statusPercent;
                    }
                    ExtractionStatusLabel.Content = "共" + fileCount.ToString() + "个文件，正在处理第" + (i + 1).ToString() + "个……";
                }
                //
                if (!excelIO.WriteExcel(saveFilePath, saveData, "PixelsValues"))
                {
                    unprocessingCount++;
                }

                geoTiffInfoList[i].dataset.Dispose();
                i++;
            }
            ExtractionStatusProgressBar.Value = 100;
            if (unprocessingCount == 0)
            {
                ExtractionStatusLabel.Content = "程序运行结束！";
            }
            else
            {
                ExtractionStatusLabel.Content = "程序运行结束！有" + unprocessingCount + "个文件未成功保存！";
            }
        }


        private void ChooseImageFileButton_Click(object sender, RoutedEventArgs e)
        {
            DeleteSelectedFileButton.IsEnabled = true;
            ClearFileListButton.IsEnabled = true;
            //
            Microsoft.Win32.OpenFileDialog openDlg = new Microsoft.Win32.OpenFileDialog
            {
                Filter = "GeoTiff文件(*.tif; *.TIF)| *.tif; *.TIF",
                Title = "选择一个或多个影像文件",
                Multiselect = true
            };
            Nullable<bool> openDlgResult = openDlg.ShowDialog();
            if (openDlgResult == true)
            {
                geoTiffInfoList = new List<RasterIO.GeoTiffInfo>();
                fileListInfo = new List<List<string>>();
                var fileNames = openDlg.FileNames;
                foreach (string fileName in fileNames)
                {
                    tmpFileInfo = new List<string> { fileName };
                    string saveXYFileName = fileName.Substring(fileName.LastIndexOf("\\") + 1,
                                                               (fileName.LastIndexOf(".") - fileName.LastIndexOf("\\") - 1));
                    tmpFileInfo.Add(saveXYFileName + "_PixelValues" + ".xlsx");
                    fileListInfo.Add(tmpFileInfo);
                    //
                    RasterIO.GeoTiffInfo geoTiffInfo = RasterIO.GetGeoTiffInfo(fileName);
                    if (geoTiffInfo.errInfo == 0)
                    {
                        System.Windows.MessageBox.Show(fileName + "是无效的影像文件，或者不受程序支持，请检查！",
                                                        "错误提示", MessageBoxButton.OK, MessageBoxImage.Error);
                    }
                    else
                    {
                        geoTiffInfoList.Add(geoTiffInfo);
                        SetImgFileInfo2TextBox(geoTiffInfo);
                    }
                }
                UpdateDataTable(fileListInfo);
                GetPixelValuesByCoordinates.GeoTiffInfoList = geoTiffInfoList;
            }
        }

        private void DeleteSelectedFileButton_Click(object sender, RoutedEventArgs e)
        {
            if (FileListDataGrid.SelectedIndex != -1 && FileListDataGrid.SelectedIndex != 0 && FileListDataGrid.SelectedIndex != dataTable.Rows.Count)
            {
                dataTable.Rows.RemoveAt(FileListDataGrid.SelectedIndex);
            }
        }

        private void ClearFileListButton_Click(object sender, RoutedEventArgs e)
        {
            fileListInfo.Clear();
            ClearDataTable();
        }

        private void ChooseCoordinatesFileButton_Click(object sender, RoutedEventArgs e)
        {
            Microsoft.Win32.OpenFileDialog openDlg = new Microsoft.Win32.OpenFileDialog
            {
                Title = "选择一个坐标文件",
                Filter = "Excel工作表(*.xlsx)|*.xlsx"
            };
            Nullable<bool> openDlgResult = openDlg.ShowDialog();
            if (openDlgResult == true)
            {
                excelInfo = new ExcelIO.ExcelInfo();
                var fileName = openDlg.FileName;
                ChooseCoordinatesFileTextBox.Text = fileName;
                ChooseWorkingSheetComboBox.Items.Clear();
                //
                ExcelIO excelIO = new ExcelIO();
                excelInfo = excelIO.GetExcelFileInfo(fileName);
                // GetPixelValuesByCoordinates.ExcelInfo = excelInfo;
                SetExcelInfo2TextBox(excelInfo);
                //
                ChooseWorkingSheetComboBox.SelectedIndex = 0;
                foreach (var field in excelInfo.defaultWorkSheetField)
                {
                    ChooseXFieldNameComboBox.Items.Add(field);
                    ChooseYFieldNameComboBox.Items.Add(field);
                }
                ChooseXFieldNameComboBox.SelectedIndex = 1;
                ChooseYFieldNameComboBox.SelectedIndex = 2;
            }
        }

        private void ChooseSaveDirButton_Click(object sender, RoutedEventArgs e)
        {
            FolderBrowserDialog saveDirDlg = new FolderBrowserDialog();
            Nullable<bool> saveDirResult = Convert.ToBoolean(saveDirDlg.ShowDialog());
            if (saveDirResult == true)
            {
                ChooseSaveDirTextBox.Text = saveDirDlg.SelectedPath;
            }
        }

        private void UOKButton_Click(object sender, RoutedEventArgs e)
        {
            ExtractionStatusProgressBar.Visibility = Visibility.Visible;
            ExtractionStatusLabel.Visibility = Visibility.Visible;
            ApplyGPVC();
        }

        private void UCancelButton_Click(object sender, RoutedEventArgs e)
        {
            Close();
        }

        private void MainWindow_FormClosing(object sender, CancelEventArgs e)
        {
            //var dlgResult = System.Windows.MessageBox.Show("退出程序？",
            //                                "提示",
            //                                MessageBoxButton.YesNo,
            //                                MessageBoxImage.Information);
            //if (dlgResult == MessageBoxResult.Yes) e.Cancel = false;
            //else e.Cancel = true;
        }

    }
}
